library(shiny)
library(tidyverse)
library(shinythemes)
library(stringi)
seabirds_cleaned_data <- read_csv("clean_data/seabirds_cleaned_data.csv")
Rows: 49020 Columns: 52
-- Column specification -------------------------------------------------------------------------------------------------------------------------------------------------------------
Delimiter: ","
chr  (19): common_name, scientific_name, species_abbreviation, age, plphase, feeding, on_water, on_ice, on_ship, in_hand, fly_by, group_sighting, ship_wake, molting, nat_feeding...
dbl  (28): record_x, record_id, wanplum, total_sighting, num_feeding, num_on_water, num_on_ice, num_fly_by, num_group_sighting, num_ship_wake, record_y, lat, long, ship_activity...
lgl   (3): sex, air_temp, salinity
dttm  (2): date, time

i Use `spec()` to retrieve the full column specification for this data.
i Specify the column types or set `show_col_types = FALSE` to quiet this message.

birds_21 <- seabirds_cleaned_data %>%
  mutate(bird_type = case_when(
  str_detect(common_name, 
             regex("shearwater", 
                   ignore_case = TRUE)) ~ "Shearwater",
  str_detect(common_name, 
             regex("albatross", 
                   ignore_case = TRUE)) ~ "Albatross",
  str_detect(common_name, 
             regex("mollymawk", 
                   ignore_case = TRUE)) ~ "Mollymawk",
  str_detect(common_name, 
             regex("petrel", 
                   ignore_case = TRUE)) ~ "Petrel",
  str_detect(common_name, 
             regex("prion", 
                   ignore_case = TRUE)) ~ "Prion",
  str_detect(common_name, 
             regex("skua", 
                   ignore_case = TRUE)) ~ "Skua",
  str_detect(common_name, 
             regex("penguin", 
                   ignore_case = TRUE)) ~ "Penguin",
  str_detect(common_name, 
             regex("tropicbird", 
                   ignore_case = TRUE)) ~ "Tropicbird",
  str_detect(common_name, 
             regex("noddy", 
                   ignore_case = TRUE)) ~ "Noddy",
  str_detect(common_name, 
             regex("tern", 
                   ignore_case = TRUE)) ~ "Tern",
  str_detect(common_name, 
             regex("gull", 
                   ignore_case = TRUE)) ~ "Gull",
  str_detect(common_name, 
             regex("booby", 
                   ignore_case = TRUE)) ~ "Booby",
  str_detect(common_name, 
             regex("frigatebird", 
                   ignore_case = TRUE)) ~ "Frigatebird",
  str_detect(common_name, 
             regex("shag", 
                   ignore_case = TRUE)) ~ "Shag",
  str_detect(common_name, 
             regex("sheathbill", 
                   ignore_case = TRUE)) ~ "Sheathbill",
  str_detect(common_name, 
             regex("fulmar", 
                   ignore_case = TRUE)) ~ "Fulmar",
  str_detect(common_name, 
             regex("gannet", 
                   ignore_case = TRUE)) ~ "Gannet",
  str_detect(common_name, 
             regex("cormorant", 
                   ignore_case = TRUE)) ~ "Cormorant",
  str_detect(common_name, 
             regex("procellaria", 
                   ignore_case = TRUE)) ~ "Procellaria",
    TRUE ~ common_name))

birds_21
# https://r-charts.com/color-palette-generator/

# https://www.statology.org/color-by-factor-ggplot2/

birds_pal <- c("#50e2ea", "#4edae5", "#4bd2df", "#49cada", "#47c2d4", 
               "#45bbcf", "#42b3c9", "#40abc4", "#3ea3be", "#3b9bb9",
               "#3993b3", "#378bae", "#3483a8", "#327ba3", "#30739d", 
               "#2e6c98", "#2b6492", "#295c8d", "#275487", "#244c82", "#22447c")

names(birds_pal) <- levels(birds_21$bird_type)

custom_colors <- scale_colour_manual(values = birds_pal)
  

birds <- c("Tropicbird" = "#50e2ea", "Tern" = "#4edae5", "Skua" = "#4bd2df", 
           "Sheathbill" = "#49cada", "Shearwater" = "#47c2d4", 
           "Shag" = "#45bbcf", "Seabird" = "#42b3c9", "Procellaria" = "#40abc4",
           "Prion" = "#3ea3be", "Petrel" = "#3b9bb9", "Penguin" = "#3993b3", 
           "Noddy" = "#378bae", "Mollymawk" = "#3483a8", "Jaeger" = "#327ba3", 
           "Gull" = "#30739d", "Gannet" = "#2e6c98", "Fulmar" = "#2b6492", 
           "Frigatebird" = "#295c8d", "Cormorant" = "#275487", 
           "Booby" = "#244c82", "Albatross" = "#22447c")

Jaeger Seabird

birds_9 %>% 
  filter(!is.na(bird_type)) %>% 
  count(bird_type)  
NA
sighting <-  birds_21 %>% 
            filter(!is.na(bird_type)) %>% 
            group_by(bird_type) %>% 
            summarise(count = sum(total_sighting, na.rm = TRUE)) %>%
            mutate(sighting_id = row_number())

sighting %>% 
    ggplot() +
    aes(y = bird_type, 
        x = count, fill = bird_type) +
    geom_col(colour = "black") +
    theme(legend.position = "none") +
    scale_x_continuous(breaks = c(1, 5, 10, 1000, 6000, 1400000),
                       limits = c(1,1400000), 
                       trans = "log10") +
    labs(y = "\n Bird Names",
         x = "Number of Birds Seen \n Log10 scale") +
    scale_fill_manual(values = birds)


# log10() as 1 or more birds are less than 10 and don't show on normal graph

1,394,468

feeding <-  birds_21 %>% 
              group_by(bird_type) %>% 
              filter(str_detect(feeding, "YES")) %>% 
              summarise(count = n()) %>% 
              mutate(feeding_id = row_number())

feeding %>% 
    ggplot() +
    aes(y = bird_type, 
        x = count, fill = bird_type) +
    geom_col(colour = "black") +
    theme(legend.position = "none") +
    scale_x_continuous(breaks = c(1, 5, 10, 100, 300, 800),
                       limits = c(1,800), 
                       trans = "log10") +
    labs(y = "\n Bird Names",
         x = "Number of Birds Seen Feeding \n Log10 scale") +
    scale_fill_manual(values = birds)

# log10() as 1 or more birds are less than 10 and don't show on normal graph
on_ship <-  birds_21 %>% 
              group_by(bird_type) %>% 
              filter(str_detect(on_ship, "YES")) %>% 
              summarise(count = n()) %>% 
              mutate(on_ship_id = row_number())

on_ship %>% 
    ggplot() +
    aes(y = bird_type, 
        x = count, fill = bird_type) +
    geom_col(colour = "black") +
    theme(legend.position = "none") +
    scale_x_continuous(breaks = c(1, 2, 3, 5, 7, 10, 60),
                       limits = c(1,60), 
                       trans = "log10") +
    labs(y = "\n Bird Names",
         x = "Number of Birds Seen On Ship") +
    scale_fill_manual(values = birds)

in_hand <-  birds_21 %>% 
              group_by(bird_type) %>% 
              filter(str_detect(in_hand, "YES")) %>% 
              summarise(count = n()) %>% 
              mutate(in_hand_id = row_number()) 

in_hand %>% 
    ggplot() +
    aes(y = bird_type, 
        x = count, fill = bird_type) +
    geom_col(colour = "black") +
    theme(legend.position = "none") +
    labs(y = "\n Bird Names",
         x = "Number of Birds Seen In Hand") +
    scale_fill_manual(values = birds)

fly_by <-  birds_21 %>% 
              group_by(bird_type) %>% 
              filter(str_detect(fly_by, "YES")) %>% 
              summarise(count = n()) %>% 
              mutate(fly_by_id = row_number())

fly_by %>% 
    ggplot() +
    aes(y = bird_type, 
        x = count, fill = bird_type) +
    geom_col(colour = "black") +
    theme(legend.position = "none") +
    scale_x_continuous(breaks = c(1, 5, 10, 1000, 6000), 
                       limits = c(1,6000), 
                       trans = "log10") +
    labs(y = "\n Bird Names",
         x = "Number of Birds Seen Flying BY\n Log10 scale") +
    scale_fill_manual(values = birds)

# log10() as 1 or more birds are less than 10 and don't show on normal graph
variants <- birds_21 %>% 
              filter(bird_type == "Albatross") %>% 
              group_by(common_name) %>% 
              summarise(count = n())
  
variants %>% 
    ggplot() +
    aes(y = common_name, 
        x = count, fill = common_name) +
    geom_col(colour = "black") +
    theme(legend.position = "none") +
    scale_x_continuous( 
                       trans = "log10") +
    labs(y = "\n Bird Names",
         x = "Number of Birds Seen Flying BY\n Log10 scale") +
    scale_fill_manual(values = birds_pal)            

variants <- birds_21 %>% 
              filter(bird_type == "Booby") %>% 
              group_by(common_name) %>% 
              summarise(count = n())
  
variants %>% 
    ggplot() +
    aes(y = common_name, 
        x = count, fill = common_name) +
    geom_col(colour = "black") +
    theme(legend.position = "none") +
    scale_x_continuous( 
                       trans = "log10") +
    labs(y = "\n Bird Names",
         x = "Number of Birds Seen Flying BY\n Log10 scale") +
    scale_fill_manual(values = birds_pal)  

variants <- birds_21 %>% 
              filter(bird_type == "Cormorant") %>% 
              group_by(common_name) %>% 
              summarise(count = n())
  
variants %>% 
    ggplot() +
    aes(y = common_name, 
        x = count, fill = common_name) +
    geom_col(colour = "black") +
    theme(legend.position = "none") +
    scale_x_continuous( 
                       trans = "log10") +
    labs(y = "\n Bird Names",
         x = "Number of Birds Seen Flying BY\n Log10 scale") +
    scale_fill_manual(values = birds_pal) 

variants <- birds_21 %>% 
              filter(bird_type == "Tropicbird") %>% 
              group_by(common_name) %>% 
              summarise(count = n())
  
variants %>% 
    ggplot() +
    aes(y = common_name, 
        x = count, fill = common_name) +
    geom_col(colour = "black") +
    theme(legend.position = "none") +
    scale_x_continuous() +
    labs(y = "\n Bird Names",
         x = "Number of Birds Seen Flying BY\n Log10 scale") +
    scale_fill_manual(values = birds_pal) 

```r
library(shiny)
library(tidyverse)
library(shinythemes)


seabirds_cleaned_data <- read_csv(\data/seabirds_cleaned_data.csv\)

<!-- rnb-source-end -->

<!-- rnb-chunk-end -->


<!-- rnb-text-begin -->



<!-- rnb-text-end -->


<!-- rnb-chunk-begin -->


<!-- rnb-source-begin eyJkYXRhIjoiYGBgclxuYGBgclxuYmlyZHNfOSA8LSBzZWFiaXJkc19jbGVhbmVkX2RhdGEgJT4lIFxuICBncm91cF9ieShjb21tb25fbmFtZSkgJT4lIFxuICBtdXRhdGUoY29tbW9uX25hbWUgPSBpZl9lbHNlKHN0cl9kZXRlY3QoY29tbW9uX25hbWUsIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXFwoP2kpc2hlYXJ3YXRlclxcKSxcXFNoZWFyd2F0ZXJcXCwgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29tbW9uX25hbWUpLFxuICAgICAgICAgY29tbW9uX25hbWUgPSBpZl9lbHNlKHN0cl9kZXRlY3QoY29tbW9uX25hbWUsIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXFwoP2kpYWxiYXRyb3NzXFwpLCBcXEFsYmF0cm9zc1xcLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbW1vbl9uYW1lKSxcbiAgICAgICAgIGNvbW1vbl9uYW1lID0gaWZfZWxzZShzdHJfZGV0ZWN0KGNvbW1vbl9uYW1lLCBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxcKD9pKW1vbGx5bWF3a1xcKSwgXFxNb2xseW1hd2tcXCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb21tb25fbmFtZSksXG4gICAgICAgICBjb21tb25fbmFtZSA9IGlmX2Vsc2Uoc3RyX2RldGVjdChjb21tb25fbmFtZSwgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcXCg/aSlwZXRyZWxcXCksIFxcUGV0cmVsXFwsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29tbW9uX25hbWUpLFxuICAgICAgICAgY29tbW9uX25hbWUgPSBpZl9lbHNlKHN0cl9kZXRlY3QoY29tbW9uX25hbWUsIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXFwoP2kpcHJpb25cXCksIFxcUHJpb25cXCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb21tb25fbmFtZSksXG4gICAgICAgICBjb21tb25fbmFtZSA9IGlmX2Vsc2Uoc3RyX2RldGVjdChjb21tb25fbmFtZSwgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcXCg/aSlza3VhXFwpLCBcXFNrdWFcXCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb21tb25fbmFtZSksXG4gICAgICAgICBjb21tb25fbmFtZSA9IGlmX2Vsc2Uoc3RyX2RldGVjdChjb21tb25fbmFtZSwgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcXCg/aSlwZW5ndWluXFwpLCBcXFBlbmd1aW5cXCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb21tb25fbmFtZSksXG4gICAgICAgICBjb21tb25fbmFtZSA9IGlmX2Vsc2Uoc3RyX2RldGVjdChjb21tb25fbmFtZSwgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBcXCg/aSlSZWQtdGFpbGVkIHRyb3BpY2JpcmRcXCksIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxcUmVkLXRhaWxlZCB0cm9waWNiaXJkXFwsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29tbW9uX25hbWUpLFxuICAgICAgICAgY29tbW9uX25hbWUgPSBpZl9lbHNlKHN0cl9kZXRlY3QoY29tbW9uX25hbWUsIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXFwoP2kpQnJvd24gbm9kZHlcXCksIFxcQnJvd24gbm9kZHlcXCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb21tb25fbmFtZSlcbiAgKSAlPiUgXG4gIGZpbHRlcihjb21tb25fbmFtZSAlaW4lIGMoXFxTaGVhcndhdGVyXFwsIFxcQWxiYXRyb3NzXFwsIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxcTW9sbHltYXdrXFwsIFxcUGV0cmVsXFwsIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxcUHJpb25cXCwgXFxTa3VhXFwsIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxcUGVuZ3VpblxcLCBcXEJyb3duIG5vZGR5XFwsIFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIFxcUmVkLXRhaWxlZCB0cm9waWNiaXJkXFwpKVxuYGBgXG5gYGAifQ== -->

```r
```r
birds_9 <- seabirds_cleaned_data %>% 
  group_by(common_name) %>% 
  mutate(common_name = if_else(str_detect(common_name, 
                                          \(?i)shearwater\),\Shearwater\, 
                               common_name),
         common_name = if_else(str_detect(common_name, 
                                          \(?i)albatross\), \Albatross\,
                               common_name),
         common_name = if_else(str_detect(common_name, 
                                          \(?i)mollymawk\), \Mollymawk\,
                               common_name),
         common_name = if_else(str_detect(common_name, 
                                          \(?i)petrel\), \Petrel\,
                               common_name),
         common_name = if_else(str_detect(common_name, 
                                          \(?i)prion\), \Prion\,
                               common_name),
         common_name = if_else(str_detect(common_name, 
                                          \(?i)skua\), \Skua\,
                               common_name),
         common_name = if_else(str_detect(common_name, 
                                          \(?i)penguin\), \Penguin\,
                               common_name),
         common_name = if_else(str_detect(common_name, 
                                          \(?i)Red-tailed tropicbird\), 
                               \Red-tailed tropicbird\,
                               common_name),
         common_name = if_else(str_detect(common_name, 
                                          \(?i)Brown noddy\), \Brown noddy\,
                               common_name)
  ) %>% 
  filter(common_name %in% c(\Shearwater\, \Albatross\, 
                            \Mollymawk\, \Petrel\, 
                            \Prion\, \Skua\, 
                            \Penguin\, \Brown noddy\, 
                            \Red-tailed tropicbird\))

<!-- rnb-source-end -->

<!-- rnb-chunk-end -->


<!-- rnb-text-begin -->




<!-- rnb-text-end -->


<!-- rnb-chunk-begin -->


<!-- rnb-source-begin eyJkYXRhIjoiYGBgclxuYGBgclxucGFsIDwtIGMoXFxTaGVhcndhdGVyXFwgPSBcXGdyZXlcXCwgXFxBbGJhdHJvc3NcXCA9IFxcYmx1ZVxcLCBcbiAgICAgICAgIFxcTW9sbHltYXdrXFwgPSBcXHllbGxvd1xcLCBcXFBldHJlbFxcID0gXFxncmVlblxcLCBcbiAgICAgICAgIFxcUHJpb25cXCA9IFxccGlua1xcLCBcXFNrdWFcXCA9IFxccHVycGxlXFwsIFxuICAgICAgICAgXFxQZW5ndWluXFwgPSBcXG9yYW5nZVxcLCBcXEJyb3duIG5vZGR5XFwgPSBcXGJyb3duXFwsIFxuICAgICAgICAgXFxSZWQtdGFpbGVkIHRyb3BpY2JpcmRcXCA9IFxccmVkXFwpXG5gYGBcbmBgYCJ9 -->

```r
```r
pal <- c(\Shearwater\ = \grey\, \Albatross\ = \blue\, 
         \Mollymawk\ = \yellow\, \Petrel\ = \green\, 
         \Prion\ = \pink\, \Skua\ = \purple\, 
         \Penguin\ = \orange\, \Brown noddy\ = \brown\, 
         \Red-tailed tropicbird\ = \red\)

<!-- rnb-source-end -->

<!-- rnb-chunk-end -->


<!-- rnb-text-begin -->



<!-- rnb-text-end -->


<!-- rnb-chunk-begin -->


<!-- rnb-source-begin eyJkYXRhIjoiYGBgclxuYGBgclxubmFtZXMoYmlyZHNfOSlcbmhlYWQoYmlyZHNfOSlcbmBgYFxuYGBgIn0= -->

```r
```r
names(birds_9)
head(birds_9)

<!-- rnb-source-end -->

<!-- rnb-chunk-end -->


<!-- rnb-text-begin -->




<!-- rnb-text-end -->


<!-- rnb-chunk-begin -->


<!-- rnb-source-begin eyJkYXRhIjoiYGBgclxuYGBgclxuXG5iaXJkc185ICU+JSBcbiAgZ3JvdXBfYnkoY29tbW9uX25hbWUpICU+JSBcbiAgbXV0YXRlKGZlZWRpbmcgPSBpZl9lbHNlKGZlZWRpbmcgJWluJSBcXFlFU1xcLCAxLCAwKSxcbiAgICAgICAgIG9uX3NoaXAgPSBpZl9lbHNlKG9uX3NoaXAgJWluJSBcXFlFU1xcLCAxLCAwKSxcbiAgICAgICAgIGluX2hhbmQgPSBpZl9lbHNlKGluX2hhbmQgJWluJSBcXFlFU1xcLCAxLCAwKSxcbiAgICAgICAgIGZseV9ieSA9IGlmX2Vsc2UoZmx5X2J5ICVpbiUgXFxZRVNcXCwgMSwgMCkpICU+JSBcbiAgc3VtbWFyaXNlKHNpZ2h0aW5nX2NvdW50ID0gc3VtKHRvdGFsX3NpZ2h0aW5nLCBuYS5ybSA9IFRSVUUpLFxuICAgICAgICAgICAgZmVlZGluZ19jb3VudCA9IHN1bShmZWVkaW5nLCBuYS5ybSA9IFRSVUUpLFxuICAgICAgICAgICAgb25fc2hpcF9jb3VudCA9IHN1bShvbl9zaGlwLCBuYS5ybSA9IFRSVUUpLFxuICAgICAgICAgICAgaW5faGFuZF9jb3VudCA9IHN1bShpbl9oYW5kLCBuYS5ybSA9IFRSVUUpLFxuICAgICAgICAgICAgZmx5X2J5X2NvdW50ID0gc3VtKGZseV9ieSwgbmEucm0gPSBUUlVFKSkgXG5gYGBcbmBgYCJ9 -->

```r
```r

birds_9 %>% 
  group_by(common_name) %>% 
  mutate(feeding = if_else(feeding %in% \YES\, 1, 0),
         on_ship = if_else(on_ship %in% \YES\, 1, 0),
         in_hand = if_else(in_hand %in% \YES\, 1, 0),
         fly_by = if_else(fly_by %in% \YES\, 1, 0)) %>% 
  summarise(sighting_count = sum(total_sighting, na.rm = TRUE),
            feeding_count = sum(feeding, na.rm = TRUE),
            on_ship_count = sum(on_ship, na.rm = TRUE),
            in_hand_count = sum(in_hand, na.rm = TRUE),
            fly_by_count = sum(fly_by, na.rm = TRUE)) 

<!-- rnb-source-end -->

<!-- rnb-chunk-end -->


<!-- rnb-text-begin -->




<!-- rnb-text-end -->


<!-- rnb-chunk-begin -->


<!-- rnb-source-begin eyJkYXRhIjoiYGBgclxubGlicmFyeShsZWFmbGV0KVxuYGBgIn0= -->

```r
library(leaflet)
Warning: package ‘leaflet’ was built under R version 4.1.2

  leaflet(data = birds_21) %>%
  addTiles() %>%  # Add default OpenStreetMap map tiles
  addMarkers(label = birds_9$common_name, clusterOptions = markerClusterOptions()) 
Assuming "long" and "lat" are longitude and latitude, respectively
Warning in validateCoords(lng, lat, funcName) :
  Data contains 32 rows with either missing or invalid lat/lon values and will be ignored
  
 # Print the map

-45.91667 165.4000

seabirds_cleaned_data
ship_data <- read_excel(here("raw_data/seabirds.xls"), 
                             sheet = "Ship data by record ID") %>% 
              clean_names()

position <- ship_data %>% 
  select(date, lat, long) %>%
  filter(!is.na(lat),
         !is.na(long)) %>% 
  group_by(date) %>% 
  summarise_if(is.numeric, mean)

position
ship_data %>% 
  select(date, lat, long) %>%
  filter(is.na(date))
tail(position)
leaflet(data = position) %>%
  addTiles() %>%  # Add default OpenStreetMap map tiles
  addMarkers(label = position$date, clusterOptions = markerClusterOptions()) 
Assuming "long" and "lat" are longitude and latitude, respectively
Warning in validateCoords(lng, lat, funcName) :
  Data contains 5 rows with either missing or invalid lat/lon values and will be ignored
  
 # Print the map

https://kateto.net/network-visualization

https://stackoverflow.com/questions/38432788/how-do-i-visualise-multiple-routes-using-leaflet-in-r

# https://rstudio.github.io/leaflet/markers.html
# first 20 quakes
df.20 <- quakes[1:20,]

getColor <- function(quakes) {
  sapply(position$date, function(date) {
  if(date <= 1979-12-31) {
    "green"
  } else if(date <= 1989-12-31) {
    "orange"
  } else {
    "red"
  } })
}

icons <- awesomeIcons(
  icon = 'ios-close',
  iconColor = 'black',
  library = 'ion',
  markerColor = getColor(position)
)

leaflet(position) %>% addTiles() %>%
  addAwesomeMarkers(~long, ~lat, icon=icons, label=~as.character(date))
getColor <- function(quakes) {
  sapply(position$date, function(date) {
  if(date %in% "^196") {
    "green"
  } else if(date  %in% "^197") {
    "orange"
  } else if(date  %in% "^198") {
    "blue"
  } else {
    "red"
  } })
}

icons <- awesomeIcons(
  icon = 'ios-close',
  iconColor = 'black',
  library = 'ion',
  markerColor = getColor(position)
)

leaflet(position) %>% addTiles() %>%
  addAwesomeMarkers(~long, ~lat, icon=icons, label=~as.character(date))
getColor <- function(quakes) {
  sapply(position$date, function(date) {
  case_when(str_detect(date, 
             regex("^196", 
                   ignore_case = TRUE)) ~ "green",
            str_detect(date, 
             regex("^197", 
                   ignore_case = TRUE)) ~ "orange",
             str_detect(date, 
             regex("^198", 
                   ignore_case = TRUE)) ~ "blue",
             str_detect(date, 
             regex("^199", 
                   ignore_case = TRUE)) ~ "red"
    
  ) })
}

icons <- awesomeIcons(
  icon = 'ios-close',
  iconColor = 'black',
  library = 'ion',
  markerColor = getColor(position)
)

leaflet(position) %>% addTiles() %>%
  addAwesomeMarkers(~long, ~lat, icon=icons, label=~as.character(date))
library(dplyr)
library(shiny)
library(leaflet)
library(readxl)
library(RColorBrewer)
library(maps)
library(leaflet.extras)
library(htmlwidgets)



data_dots = read_csv("test4.csv")
Rows: 8 Columns: 14
-- Column specification -------------------------------------------------------------------------------------------------------------------------------------------------------------
Delimiter: ","
chr (6): Name, ship_date, delivery_date, ShipmentID, Dcity, Origin
dbl (8): Dzip, Dlong, Dlat, Route, Seq, Ozip, Olong, Olat

i Use `spec()` to retrieve the full column specification for this data.
i Specify the column types or set `show_col_types = FALSE` to quiet this message.
ui <- bootstrapPage(
  tags$style(type = "text/css", "html, body {width:100%;height:100%}"),
  leafletOutput("map", width = "100%", height = "100%"),
  absolutePanel(top = 10, right = 10,

                dateRangeInput("dateRange", "Date Range Input", start =  min(data_dots$ship_date), end = max(data_dots$ship_date))


  )
)
Warning: Couldn't coerce the `end` argument to a date string with format yyyy-mm-dd
server <- function(input, output) {

  #n <- 60
  qual_col_pals = brewer.pal.info[brewer.pal.info$category == 'qual', ]
  col_vector = unlist(mapply(brewer.pal, qual_col_pals$maxcolors, rownames(qual_col_pals)))


  myMap = leaflet("map") %>% 
    addTiles(group = "Base") %>%
    addProviderTiles(providers$CartoDB.Positron, group = "Grey") %>%
    addResetMapButton()


  rv <- reactiveValues(
    filteredData =data_dots,
    ids = unique(data_dots$Route)
  )

  observeEvent(input$dateRange, 
               {rv$filteredData = data_dots[as.Date(data_dots$ship_date) >= input$dateRange[1] & as.Date(data_dots$ship_date) <= input$dateRange[2],]

               rv$ids = unique(rv$filteredData$Route)
               }

  )



  # Initiate the map
  output$map <- renderLeaflet({

    for (i in rv$ids) {
      #print(i)
      myMap = myMap %>%
        addPolylines(
          data = subset(rv$filteredData, Route == i),
          weight = 3,
          color = sample(col_vector, 1),
          opacity = 0.8,
          smoothFactor = 1,
          lng = ~Dlong, 
          lat = ~Dlat,
          highlight = highlightOptions(
            weight = 5,
            color = "blue",
            bringToFront = TRUE
          ),
          label = ~ as.character(ShipmentID),
          popup = ~ as.character(ShipmentID),
          group = "test"
        )

    }
    myMap


  })


}
shinyApp(ui = ui, server = server)

Listening on http://127.0.0.1:4277
Warning: Error in charToDate: character string is not in a standard unambiguous format
  [No stack trace available]
NA
data_dots %>% 
  mutate(ship_date = as.Date(ship_date, "%y/%m/%d"),
         delivery_date = as.Date(delivery_date, "%y/%m/%d"))
LS0tDQp0aXRsZTogIlIgTm90ZWJvb2siDQpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sNCi0tLQ0KDQpgYGB7cn0NCmxpYnJhcnkoc2hpbnkpDQpsaWJyYXJ5KHRpZHl2ZXJzZSkNCmxpYnJhcnkoc2hpbnl0aGVtZXMpDQpsaWJyYXJ5KHN0cmluZ2kpDQpsaWJyYXJ5KFJDb2xvckJyZXdlcikNCmBgYA0KDQpgYGB7cn0NCnNlYWJpcmRzX2NsZWFuZWRfZGF0YSA8LSByZWFkX2NzdigiY2xlYW5fZGF0YS9zZWFiaXJkc19jbGVhbmVkX2RhdGEuY3N2IikNCmBgYA0KDQoNCg0KDQpgYGB7cn0NCg0KYmlyZHNfMjEgPC0gc2VhYmlyZHNfY2xlYW5lZF9kYXRhICU+JQ0KICBtdXRhdGUoYmlyZF90eXBlID0gY2FzZV93aGVuKA0KICBzdHJfZGV0ZWN0KGNvbW1vbl9uYW1lLCANCiAgICAgICAgICAgICByZWdleCgic2hlYXJ3YXRlciIsIA0KICAgICAgICAgICAgICAgICAgIGlnbm9yZV9jYXNlID0gVFJVRSkpIH4gIlNoZWFyd2F0ZXIiLA0KICBzdHJfZGV0ZWN0KGNvbW1vbl9uYW1lLCANCiAgICAgICAgICAgICByZWdleCgiYWxiYXRyb3NzIiwgDQogICAgICAgICAgICAgICAgICAgaWdub3JlX2Nhc2UgPSBUUlVFKSkgfiAiQWxiYXRyb3NzIiwNCiAgc3RyX2RldGVjdChjb21tb25fbmFtZSwgDQogICAgICAgICAgICAgcmVnZXgoIm1vbGx5bWF3ayIsIA0KICAgICAgICAgICAgICAgICAgIGlnbm9yZV9jYXNlID0gVFJVRSkpIH4gIk1vbGx5bWF3ayIsDQogIHN0cl9kZXRlY3QoY29tbW9uX25hbWUsIA0KICAgICAgICAgICAgIHJlZ2V4KCJwZXRyZWwiLCANCiAgICAgICAgICAgICAgICAgICBpZ25vcmVfY2FzZSA9IFRSVUUpKSB+ICJQZXRyZWwiLA0KICBzdHJfZGV0ZWN0KGNvbW1vbl9uYW1lLCANCiAgICAgICAgICAgICByZWdleCgicHJpb24iLCANCiAgICAgICAgICAgICAgICAgICBpZ25vcmVfY2FzZSA9IFRSVUUpKSB+ICJQcmlvbiIsDQogIHN0cl9kZXRlY3QoY29tbW9uX25hbWUsIA0KICAgICAgICAgICAgIHJlZ2V4KCJza3VhIiwgDQogICAgICAgICAgICAgICAgICAgaWdub3JlX2Nhc2UgPSBUUlVFKSkgfiAiU2t1YSIsDQogIHN0cl9kZXRlY3QoY29tbW9uX25hbWUsIA0KICAgICAgICAgICAgIHJlZ2V4KCJwZW5ndWluIiwgDQogICAgICAgICAgICAgICAgICAgaWdub3JlX2Nhc2UgPSBUUlVFKSkgfiAiUGVuZ3VpbiIsDQogIHN0cl9kZXRlY3QoY29tbW9uX25hbWUsIA0KICAgICAgICAgICAgIHJlZ2V4KCJ0cm9waWNiaXJkIiwgDQogICAgICAgICAgICAgICAgICAgaWdub3JlX2Nhc2UgPSBUUlVFKSkgfiAiVHJvcGljYmlyZCIsDQogIHN0cl9kZXRlY3QoY29tbW9uX25hbWUsIA0KICAgICAgICAgICAgIHJlZ2V4KCJub2RkeSIsIA0KICAgICAgICAgICAgICAgICAgIGlnbm9yZV9jYXNlID0gVFJVRSkpIH4gIk5vZGR5IiwNCiAgc3RyX2RldGVjdChjb21tb25fbmFtZSwgDQogICAgICAgICAgICAgcmVnZXgoInRlcm4iLCANCiAgICAgICAgICAgICAgICAgICBpZ25vcmVfY2FzZSA9IFRSVUUpKSB+ICJUZXJuIiwNCiAgc3RyX2RldGVjdChjb21tb25fbmFtZSwgDQogICAgICAgICAgICAgcmVnZXgoImd1bGwiLCANCiAgICAgICAgICAgICAgICAgICBpZ25vcmVfY2FzZSA9IFRSVUUpKSB+ICJHdWxsIiwNCiAgc3RyX2RldGVjdChjb21tb25fbmFtZSwgDQogICAgICAgICAgICAgcmVnZXgoImJvb2J5IiwgDQogICAgICAgICAgICAgICAgICAgaWdub3JlX2Nhc2UgPSBUUlVFKSkgfiAiQm9vYnkiLA0KICBzdHJfZGV0ZWN0KGNvbW1vbl9uYW1lLCANCiAgICAgICAgICAgICByZWdleCgiZnJpZ2F0ZWJpcmQiLCANCiAgICAgICAgICAgICAgICAgICBpZ25vcmVfY2FzZSA9IFRSVUUpKSB+ICJGcmlnYXRlYmlyZCIsDQogIHN0cl9kZXRlY3QoY29tbW9uX25hbWUsIA0KICAgICAgICAgICAgIHJlZ2V4KCJzaGFnIiwgDQogICAgICAgICAgICAgICAgICAgaWdub3JlX2Nhc2UgPSBUUlVFKSkgfiAiU2hhZyIsDQogIHN0cl9kZXRlY3QoY29tbW9uX25hbWUsIA0KICAgICAgICAgICAgIHJlZ2V4KCJzaGVhdGhiaWxsIiwgDQogICAgICAgICAgICAgICAgICAgaWdub3JlX2Nhc2UgPSBUUlVFKSkgfiAiU2hlYXRoYmlsbCIsDQogIHN0cl9kZXRlY3QoY29tbW9uX25hbWUsIA0KICAgICAgICAgICAgIHJlZ2V4KCJmdWxtYXIiLCANCiAgICAgICAgICAgICAgICAgICBpZ25vcmVfY2FzZSA9IFRSVUUpKSB+ICJGdWxtYXIiLA0KICBzdHJfZGV0ZWN0KGNvbW1vbl9uYW1lLCANCiAgICAgICAgICAgICByZWdleCgiZ2FubmV0IiwgDQogICAgICAgICAgICAgICAgICAgaWdub3JlX2Nhc2UgPSBUUlVFKSkgfiAiR2FubmV0IiwNCiAgc3RyX2RldGVjdChjb21tb25fbmFtZSwgDQogICAgICAgICAgICAgcmVnZXgoImNvcm1vcmFudCIsIA0KICAgICAgICAgICAgICAgICAgIGlnbm9yZV9jYXNlID0gVFJVRSkpIH4gIkNvcm1vcmFudCIsDQogIHN0cl9kZXRlY3QoY29tbW9uX25hbWUsIA0KICAgICAgICAgICAgIHJlZ2V4KCJwcm9jZWxsYXJpYSIsIA0KICAgICAgICAgICAgICAgICAgIGlnbm9yZV9jYXNlID0gVFJVRSkpIH4gIlByb2NlbGxhcmlhIiwNCiAgICBUUlVFIH4gY29tbW9uX25hbWUpKQ0KDQpiaXJkc18yMQ0KYGBgDQpgYGB7cn0NCiMgaHR0cHM6Ly9yLWNoYXJ0cy5jb20vY29sb3ItcGFsZXR0ZS1nZW5lcmF0b3IvDQoNCiMgaHR0cHM6Ly93d3cuc3RhdG9sb2d5Lm9yZy9jb2xvci1ieS1mYWN0b3ItZ2dwbG90Mi8NCg0KYmlyZHNfcGFsIDwtIGMoIiM1MGUyZWEiLCAiIzRlZGFlNSIsICIjNGJkMmRmIiwgIiM0OWNhZGEiLCAiIzQ3YzJkNCIsIA0KICAgICAgICAgICAgICAgIiM0NWJiY2YiLCAiIzQyYjNjOSIsICIjNDBhYmM0IiwgIiMzZWEzYmUiLCAiIzNiOWJiOSIsDQogICAgICAgICAgICAgICAiIzM5OTNiMyIsICIjMzc4YmFlIiwgIiMzNDgzYTgiLCAiIzMyN2JhMyIsICIjMzA3MzlkIiwgDQogICAgICAgICAgICAgICAiIzJlNmM5OCIsICIjMmI2NDkyIiwgIiMyOTVjOGQiLCAiIzI3NTQ4NyIsICIjMjQ0YzgyIiwgIiMyMjQ0N2MiKQ0KDQpuYW1lcyhiaXJkc19wYWwpIDwtIGxldmVscyhiaXJkc18yMSRiaXJkX3R5cGUpDQoNCmN1c3RvbV9jb2xvcnMgPC0gc2NhbGVfY29sb3VyX21hbnVhbCh2YWx1ZXMgPSBiaXJkc19wYWwpDQogIA0KDQpiaXJkcyA8LSBjKCJUcm9waWNiaXJkIiA9ICIjNTBlMmVhIiwgIlRlcm4iID0gIiM0ZWRhZTUiLCAiU2t1YSIgPSAiIzRiZDJkZiIsIA0KICAgICAgICAgICAiU2hlYXRoYmlsbCIgPSAiIzQ5Y2FkYSIsICJTaGVhcndhdGVyIiA9ICIjNDdjMmQ0IiwgDQogICAgICAgICAgICJTaGFnIiA9ICIjNDViYmNmIiwgIlNlYWJpcmQiID0gIiM0MmIzYzkiLCAiUHJvY2VsbGFyaWEiID0gIiM0MGFiYzQiLA0KICAgICAgICAgICAiUHJpb24iID0gIiMzZWEzYmUiLCAiUGV0cmVsIiA9ICIjM2I5YmI5IiwgIlBlbmd1aW4iID0gIiMzOTkzYjMiLCANCiAgICAgICAgICAgIk5vZGR5IiA9ICIjMzc4YmFlIiwgIk1vbGx5bWF3ayIgPSAiIzM0ODNhOCIsICJKYWVnZXIiID0gIiMzMjdiYTMiLCANCiAgICAgICAgICAgIkd1bGwiID0gIiMzMDczOWQiLCAiR2FubmV0IiA9ICIjMmU2Yzk4IiwgIkZ1bG1hciIgPSAiIzJiNjQ5MiIsIA0KICAgICAgICAgICAiRnJpZ2F0ZWJpcmQiID0gIiMyOTVjOGQiLCAiQ29ybW9yYW50IiA9ICIjMjc1NDg3IiwgDQogICAgICAgICAgICJCb29ieSIgPSAiIzI0NGM4MiIsICJBbGJhdHJvc3MiID0gIiMyMjQ0N2MiKQ0KDQoNCmBgYA0KDQpKYWVnZXINClNlYWJpcmQNCmBgYHtyfQ0KYmlyZHNfMjEgJT4lIA0KICBmaWx0ZXIoIWlzLm5hKGJpcmRfdHlwZSkpICU+JSANCiAgY291bnQoYmlyZF90eXBlKSAgDQogIA0KYGBgDQoNCg0KYGBge3J9DQpzaWdodGluZyA8LSAgYmlyZHNfMjEgJT4lIA0KICAgICAgICAgICAgZmlsdGVyKCFpcy5uYShiaXJkX3R5cGUpKSAlPiUgDQogICAgICAgICAgICBncm91cF9ieShiaXJkX3R5cGUpICU+JSANCiAgICAgICAgICAgIHN1bW1hcmlzZShjb3VudCA9IHN1bSh0b3RhbF9zaWdodGluZywgbmEucm0gPSBUUlVFKSkgJT4lDQogICAgICAgICAgICBtdXRhdGUoc2lnaHRpbmdfaWQgPSByb3dfbnVtYmVyKCkpDQoNCnNpZ2h0aW5nICU+JSANCiAgICBnZ3Bsb3QoKSArDQogICAgYWVzKHkgPSBiaXJkX3R5cGUsIA0KICAgICAgICB4ID0gY291bnQsIGZpbGwgPSBiaXJkX3R5cGUpICsNCiAgICBnZW9tX2NvbChjb2xvdXIgPSAiYmxhY2siKSArDQogICAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiKSArDQogICAgc2NhbGVfeF9jb250aW51b3VzKGJyZWFrcyA9IGMoMSwgNSwgMTAsIDEwMDAsIDYwMDAsIDE0MDAwMDApLA0KICAgICAgICAgICAgICAgICAgICAgICBsaW1pdHMgPSBjKDEsMTQwMDAwMCksIA0KICAgICAgICAgICAgICAgICAgICAgICB0cmFucyA9ICJsb2cxMCIpICsNCiAgICBsYWJzKHkgPSAiXG4gQmlyZCBOYW1lcyIsDQogICAgICAgICB4ID0gIk51bWJlciBvZiBCaXJkcyBTZWVuIFxuIExvZzEwIHNjYWxlIikgKw0KICAgIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IGJpcmRzKQ0KDQojIGxvZzEwKCkgYXMgMSBvciBtb3JlIGJpcmRzIGFyZSBsZXNzIHRoYW4gMTAgYW5kIGRvbid0IHNob3cgb24gbm9ybWFsIGdyYXBoDQpgYGANCjEsMzk0LDQ2OA0KDQpgYGB7cn0NCmZlZWRpbmcgPC0gIGJpcmRzXzIxICU+JSANCiAgICAgICAgICAgICAgZ3JvdXBfYnkoYmlyZF90eXBlKSAlPiUgDQogICAgICAgICAgICAgIGZpbHRlcihzdHJfZGV0ZWN0KGZlZWRpbmcsICJZRVMiKSkgJT4lIA0KICAgICAgICAgICAgICBzdW1tYXJpc2UoY291bnQgPSBuKCkpICU+JSANCiAgICAgICAgICAgICAgbXV0YXRlKGZlZWRpbmdfaWQgPSByb3dfbnVtYmVyKCkpDQoNCmZlZWRpbmcgJT4lIA0KICAgIGdncGxvdCgpICsNCiAgICBhZXMoeSA9IGJpcmRfdHlwZSwgDQogICAgICAgIHggPSBjb3VudCwgZmlsbCA9IGJpcmRfdHlwZSkgKw0KICAgIGdlb21fY29sKGNvbG91ciA9ICJibGFjayIpICsNCiAgICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAibm9uZSIpICsNCiAgICBzY2FsZV94X2NvbnRpbnVvdXMoYnJlYWtzID0gYygxLCA1LCAxMCwgMTAwLCAzMDAsIDgwMCksDQogICAgICAgICAgICAgICAgICAgICAgIGxpbWl0cyA9IGMoMSw4MDApLCANCiAgICAgICAgICAgICAgICAgICAgICAgdHJhbnMgPSAibG9nMTAiKSArDQogICAgbGFicyh5ID0gIlxuIEJpcmQgTmFtZXMiLA0KICAgICAgICAgeCA9ICJOdW1iZXIgb2YgQmlyZHMgU2VlbiBGZWVkaW5nIFxuIExvZzEwIHNjYWxlIikgKw0KICAgIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IGJpcmRzKQ0KIyBsb2cxMCgpIGFzIDEgb3IgbW9yZSBiaXJkcyBhcmUgbGVzcyB0aGFuIDEwIGFuZCBkb24ndCBzaG93IG9uIG5vcm1hbCBncmFwaA0KYGBgDQoNCmBgYHtyfQ0Kb25fc2hpcCA8LSAgYmlyZHNfMjEgJT4lIA0KICAgICAgICAgICAgICBncm91cF9ieShiaXJkX3R5cGUpICU+JSANCiAgICAgICAgICAgICAgZmlsdGVyKHN0cl9kZXRlY3Qob25fc2hpcCwgIllFUyIpKSAlPiUgDQogICAgICAgICAgICAgIHN1bW1hcmlzZShjb3VudCA9IG4oKSkgJT4lIA0KICAgICAgICAgICAgICBtdXRhdGUob25fc2hpcF9pZCA9IHJvd19udW1iZXIoKSkNCg0Kb25fc2hpcCAlPiUgDQogICAgZ2dwbG90KCkgKw0KICAgIGFlcyh5ID0gYmlyZF90eXBlLCANCiAgICAgICAgeCA9IGNvdW50LCBmaWxsID0gYmlyZF90eXBlKSArDQogICAgZ2VvbV9jb2woY29sb3VyID0gImJsYWNrIikgKw0KICAgIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIikgKw0KICAgIHNjYWxlX3hfY29udGludW91cyhicmVha3MgPSBjKDEsIDIsIDMsIDUsIDcsIDEwLCA2MCksDQogICAgICAgICAgICAgICAgICAgICAgIGxpbWl0cyA9IGMoMSw2MCksIA0KICAgICAgICAgICAgICAgICAgICAgICB0cmFucyA9ICJsb2cxMCIpICsNCiAgICBsYWJzKHkgPSAiXG4gQmlyZCBOYW1lcyIsDQogICAgICAgICB4ID0gIk51bWJlciBvZiBCaXJkcyBTZWVuIE9uIFNoaXAiKSArDQogICAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gYmlyZHMpDQpgYGANCg0KDQpgYGB7cn0NCmluX2hhbmQgPC0gIGJpcmRzXzIxICU+JSANCiAgICAgICAgICAgICAgZ3JvdXBfYnkoYmlyZF90eXBlKSAlPiUgDQogICAgICAgICAgICAgIGZpbHRlcihzdHJfZGV0ZWN0KGluX2hhbmQsICJZRVMiKSkgJT4lIA0KICAgICAgICAgICAgICBzdW1tYXJpc2UoY291bnQgPSBuKCkpICU+JSANCiAgICAgICAgICAgICAgbXV0YXRlKGluX2hhbmRfaWQgPSByb3dfbnVtYmVyKCkpIA0KDQppbl9oYW5kICU+JSANCiAgICBnZ3Bsb3QoKSArDQogICAgYWVzKHkgPSBiaXJkX3R5cGUsIA0KICAgICAgICB4ID0gY291bnQsIGZpbGwgPSBiaXJkX3R5cGUpICsNCiAgICBnZW9tX2NvbChjb2xvdXIgPSAiYmxhY2siKSArDQogICAgdGhlbWUobGVnZW5kLnBvc2l0aW9uID0gIm5vbmUiKSArDQogICAgbGFicyh5ID0gIlxuIEJpcmQgTmFtZXMiLA0KICAgICAgICAgeCA9ICJOdW1iZXIgb2YgQmlyZHMgU2VlbiBJbiBIYW5kIikgKw0KICAgIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IGJpcmRzKQ0KYGBgDQoNCg0KYGBge3J9DQpmbHlfYnkgPC0gIGJpcmRzXzIxICU+JSANCiAgICAgICAgICAgICAgZ3JvdXBfYnkoYmlyZF90eXBlKSAlPiUgDQogICAgICAgICAgICAgIGZpbHRlcihzdHJfZGV0ZWN0KGZseV9ieSwgIllFUyIpKSAlPiUgDQogICAgICAgICAgICAgIHN1bW1hcmlzZShjb3VudCA9IG4oKSkgJT4lIA0KICAgICAgICAgICAgICBtdXRhdGUoZmx5X2J5X2lkID0gcm93X251bWJlcigpKQ0KDQpmbHlfYnkgJT4lIA0KICAgIGdncGxvdCgpICsNCiAgICBhZXMoeSA9IGJpcmRfdHlwZSwgDQogICAgICAgIHggPSBjb3VudCwgZmlsbCA9IGJpcmRfdHlwZSkgKw0KICAgIGdlb21fY29sKGNvbG91ciA9ICJibGFjayIpICsNCiAgICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAibm9uZSIpICsNCiAgICBzY2FsZV94X2NvbnRpbnVvdXMoYnJlYWtzID0gYygxLCA1LCAxMCwgMTAwMCwgNjAwMCksIA0KICAgICAgICAgICAgICAgICAgICAgICBsaW1pdHMgPSBjKDEsNjAwMCksIA0KICAgICAgICAgICAgICAgICAgICAgICB0cmFucyA9ICJsb2cxMCIpICsNCiAgICBsYWJzKHkgPSAiXG4gQmlyZCBOYW1lcyIsDQogICAgICAgICB4ID0gIk51bWJlciBvZiBCaXJkcyBTZWVuIEZseWluZyBCWVxuIExvZzEwIHNjYWxlIikgKw0KICAgIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IGJpcmRzKQ0KIyBsb2cxMCgpIGFzIDEgb3IgbW9yZSBiaXJkcyBhcmUgbGVzcyB0aGFuIDEwIGFuZCBkb24ndCBzaG93IG9uIG5vcm1hbCBncmFwaA0KYGBgDQoNCg0KYGBge3J9DQp2YXJpYW50cyA8LSBiaXJkc18yMSAlPiUgDQogICAgICAgICAgICAgIGZpbHRlcihiaXJkX3R5cGUgPT0gIkFsYmF0cm9zcyIpICU+JSANCiAgICAgICAgICAgICAgZ3JvdXBfYnkoY29tbW9uX25hbWUpICU+JSANCiAgICAgICAgICAgICAgc3VtbWFyaXNlKGNvdW50ID0gbigpKQ0KICANCnZhcmlhbnRzICU+JSANCiAgICBnZ3Bsb3QoKSArDQogICAgYWVzKHkgPSBjb21tb25fbmFtZSwgDQogICAgICAgIHggPSBjb3VudCwgZmlsbCA9IGNvbW1vbl9uYW1lKSArDQogICAgZ2VvbV9jb2woY29sb3VyID0gImJsYWNrIikgKw0KICAgIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIikgKw0KICAgIHNjYWxlX3hfY29udGludW91cyggDQogICAgICAgICAgICAgICAgICAgICAgIHRyYW5zID0gImxvZzEwIikgKw0KICAgIGxhYnMoeSA9ICJcbiBCaXJkIE5hbWVzIiwNCiAgICAgICAgIHggPSAiTnVtYmVyIG9mIEJpcmRzIFNlZW4gRmx5aW5nIEJZXG4gTG9nMTAgc2NhbGUiKSArDQogICAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gYmlyZHNfcGFsKSAgICAgICAgICAgIA0KYGBgDQoNCmBgYHtyfQ0KdmFyaWFudHMgPC0gYmlyZHNfMjEgJT4lIA0KICAgICAgICAgICAgICBmaWx0ZXIoYmlyZF90eXBlID09ICJCb29ieSIpICU+JSANCiAgICAgICAgICAgICAgZ3JvdXBfYnkoY29tbW9uX25hbWUpICU+JSANCiAgICAgICAgICAgICAgc3VtbWFyaXNlKGNvdW50ID0gbigpKQ0KICANCnZhcmlhbnRzICU+JSANCiAgICBnZ3Bsb3QoKSArDQogICAgYWVzKHkgPSBjb21tb25fbmFtZSwgDQogICAgICAgIHggPSBjb3VudCwgZmlsbCA9IGNvbW1vbl9uYW1lKSArDQogICAgZ2VvbV9jb2woY29sb3VyID0gImJsYWNrIikgKw0KICAgIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIikgKw0KICAgIHNjYWxlX3hfY29udGludW91cyggDQogICAgICAgICAgICAgICAgICAgICAgIHRyYW5zID0gImxvZzEwIikgKw0KICAgIGxhYnMoeSA9ICJcbiBCaXJkIE5hbWVzIiwNCiAgICAgICAgIHggPSAiTnVtYmVyIG9mIEJpcmRzIFNlZW4gRmx5aW5nIEJZXG4gTG9nMTAgc2NhbGUiKSArDQogICAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gYmlyZHNfcGFsKSAgDQpgYGANCg0KYGBge3J9DQp2YXJpYW50cyA8LSBiaXJkc18yMSAlPiUgDQogICAgICAgICAgICAgIGZpbHRlcihiaXJkX3R5cGUgPT0gIkNvcm1vcmFudCIpICU+JSANCiAgICAgICAgICAgICAgZ3JvdXBfYnkoY29tbW9uX25hbWUpICU+JSANCiAgICAgICAgICAgICAgc3VtbWFyaXNlKGNvdW50ID0gbigpKQ0KICANCnZhcmlhbnRzICU+JSANCiAgICBnZ3Bsb3QoKSArDQogICAgYWVzKHkgPSBjb21tb25fbmFtZSwgDQogICAgICAgIHggPSBjb3VudCwgZmlsbCA9IGNvbW1vbl9uYW1lKSArDQogICAgZ2VvbV9jb2woY29sb3VyID0gImJsYWNrIikgKw0KICAgIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIikgKw0KICAgIHNjYWxlX3hfY29udGludW91cyggDQogICAgICAgICAgICAgICAgICAgICAgIHRyYW5zID0gImxvZzEwIikgKw0KICAgIGxhYnMoeSA9ICJcbiBCaXJkIE5hbWVzIiwNCiAgICAgICAgIHggPSAiTnVtYmVyIG9mIEJpcmRzIFNlZW4gRmx5aW5nIEJZXG4gTG9nMTAgc2NhbGUiKSArDQogICAgc2NhbGVfZmlsbF9tYW51YWwodmFsdWVzID0gYmlyZHNfcGFsKSANCmBgYA0KDQpgYGB7cn0NCnZhcmlhbnRzIDwtIGJpcmRzXzIxICU+JSANCiAgICAgICAgICAgICAgZmlsdGVyKGJpcmRfdHlwZSA9PSAiVHJvcGljYmlyZCIpICU+JSANCiAgICAgICAgICAgICAgZ3JvdXBfYnkoY29tbW9uX25hbWUpICU+JSANCiAgICAgICAgICAgICAgc3VtbWFyaXNlKGNvdW50ID0gbigpKQ0KICANCnZhcmlhbnRzICU+JSANCiAgICBnZ3Bsb3QoKSArDQogICAgYWVzKHkgPSBjb21tb25fbmFtZSwgDQogICAgICAgIHggPSBjb3VudCwgZmlsbCA9IGNvbW1vbl9uYW1lKSArDQogICAgZ2VvbV9jb2woY29sb3VyID0gImJsYWNrIikgKw0KICAgIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIikgKw0KICAgIHNjYWxlX3hfY29udGludW91cygpICsNCiAgICBsYWJzKHkgPSAiXG4gQmlyZCBOYW1lcyIsDQogICAgICAgICB4ID0gIk51bWJlciBvZiBCaXJkcyBTZWVuIEZseWluZyBCWVxuIExvZzEwIHNjYWxlIikgKw0KICAgIHNjYWxlX2ZpbGxfbWFudWFsKHZhbHVlcyA9IGJpcmRzX3BhbCkgDQpgYGANCg0KDQoNCg0KDQoNCg0KDQpgYGB7cn0NCmxpYnJhcnkoc2hpbnkpDQpsaWJyYXJ5KHRpZHl2ZXJzZSkNCmxpYnJhcnkoc2hpbnl0aGVtZXMpDQoNCg0KI3NlYWJpcmRzX2NsZWFuZWRfZGF0YSA8LSByZWFkX2NzdigiZGF0YS9zZWFiaXJkc19jbGVhbmVkX2RhdGEuY3N2IikNCmBgYA0KDQpgYGB7cn0NCmJpcmRzXzkgPC0gc2VhYmlyZHNfY2xlYW5lZF9kYXRhICU+JSANCiAgZ3JvdXBfYnkoY29tbW9uX25hbWUpICU+JSANCiAgbXV0YXRlKGNvbW1vbl9uYW1lID0gaWZfZWxzZShzdHJfZGV0ZWN0KGNvbW1vbl9uYW1lLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIoP2kpc2hlYXJ3YXRlciIpLCJTaGVhcndhdGVyIiwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29tbW9uX25hbWUpLA0KICAgICAgICAgY29tbW9uX25hbWUgPSBpZl9lbHNlKHN0cl9kZXRlY3QoY29tbW9uX25hbWUsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIig/aSlhbGJhdHJvc3MiKSwgIkFsYmF0cm9zcyIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29tbW9uX25hbWUpLA0KICAgICAgICAgY29tbW9uX25hbWUgPSBpZl9lbHNlKHN0cl9kZXRlY3QoY29tbW9uX25hbWUsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIig/aSltb2xseW1hd2siKSwgIk1vbGx5bWF3ayIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29tbW9uX25hbWUpLA0KICAgICAgICAgY29tbW9uX25hbWUgPSBpZl9lbHNlKHN0cl9kZXRlY3QoY29tbW9uX25hbWUsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIig/aSlwZXRyZWwiKSwgIlBldHJlbCIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29tbW9uX25hbWUpLA0KICAgICAgICAgY29tbW9uX25hbWUgPSBpZl9lbHNlKHN0cl9kZXRlY3QoY29tbW9uX25hbWUsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIig/aSlwcmlvbiIpLCAiUHJpb24iLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbW1vbl9uYW1lKSwNCiAgICAgICAgIGNvbW1vbl9uYW1lID0gaWZfZWxzZShzdHJfZGV0ZWN0KGNvbW1vbl9uYW1lLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICIoP2kpc2t1YSIpLCAiU2t1YSIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29tbW9uX25hbWUpLA0KICAgICAgICAgY29tbW9uX25hbWUgPSBpZl9lbHNlKHN0cl9kZXRlY3QoY29tbW9uX25hbWUsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIig/aSlwZW5ndWluIiksICJQZW5ndWluIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb21tb25fbmFtZSksDQogICAgICAgICBjb21tb25fbmFtZSA9IGlmX2Vsc2Uoc3RyX2RldGVjdChjb21tb25fbmFtZSwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiKD9pKVJlZC10YWlsZWQgdHJvcGljYmlyZCIpLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiUmVkLXRhaWxlZCB0cm9waWNiaXJkIiwNCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb21tb25fbmFtZSksDQogICAgICAgICBjb21tb25fbmFtZSA9IGlmX2Vsc2Uoc3RyX2RldGVjdChjb21tb25fbmFtZSwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiKD9pKUJyb3duIG5vZGR5IiksICJCcm93biBub2RkeSIsDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29tbW9uX25hbWUpDQogICkgJT4lIA0KICBmaWx0ZXIoY29tbW9uX25hbWUgJWluJSBjKCJTaGVhcndhdGVyIiwgIkFsYmF0cm9zcyIsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICJNb2xseW1hd2siLCAiUGV0cmVsIiwgDQogICAgICAgICAgICAgICAgICAgICAgICAgICAgIlByaW9uIiwgIlNrdWEiLCANCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAiUGVuZ3VpbiIsICJCcm93biBub2RkeSIsIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICJSZWQtdGFpbGVkIHRyb3BpY2JpcmQiKSkNCmBgYA0KDQoNCmBgYHtyfQ0KcGFsIDwtIGMoIlNoZWFyd2F0ZXIiID0gImdyZXkiLCAiQWxiYXRyb3NzIiA9ICJibHVlIiwgDQogICAgICAgICAiTW9sbHltYXdrIiA9ICJ5ZWxsb3ciLCAiUGV0cmVsIiA9ICJncmVlbiIsIA0KICAgICAgICAgIlByaW9uIiA9ICJwaW5rIiwgIlNrdWEiID0gInB1cnBsZSIsIA0KICAgICAgICAgIlBlbmd1aW4iID0gIm9yYW5nZSIsICJCcm93biBub2RkeSIgPSAiYnJvd24iLCANCiAgICAgICAgICJSZWQtdGFpbGVkIHRyb3BpY2JpcmQiID0gInJlZCIpDQpgYGANCg0KYGBge3J9DQpuYW1lcyhiaXJkc185KQ0KaGVhZChiaXJkc185KQ0KYGBgDQoNCg0KYGBge3J9DQoNCmJpcmRzXzkgJT4lIA0KICBncm91cF9ieShjb21tb25fbmFtZSkgJT4lIA0KICBtdXRhdGUoZmVlZGluZyA9IGlmX2Vsc2UoZmVlZGluZyAlaW4lICJZRVMiLCAxLCAwKSwNCiAgICAgICAgIG9uX3NoaXAgPSBpZl9lbHNlKG9uX3NoaXAgJWluJSAiWUVTIiwgMSwgMCksDQogICAgICAgICBpbl9oYW5kID0gaWZfZWxzZShpbl9oYW5kICVpbiUgIllFUyIsIDEsIDApLA0KICAgICAgICAgZmx5X2J5ID0gaWZfZWxzZShmbHlfYnkgJWluJSAiWUVTIiwgMSwgMCkpICU+JSANCiAgc3VtbWFyaXNlKHNpZ2h0aW5nX2NvdW50ID0gc3VtKHRvdGFsX3NpZ2h0aW5nLCBuYS5ybSA9IFRSVUUpLA0KICAgICAgICAgICAgZmVlZGluZ19jb3VudCA9IHN1bShmZWVkaW5nLCBuYS5ybSA9IFRSVUUpLA0KICAgICAgICAgICAgb25fc2hpcF9jb3VudCA9IHN1bShvbl9zaGlwLCBuYS5ybSA9IFRSVUUpLA0KICAgICAgICAgICAgaW5faGFuZF9jb3VudCA9IHN1bShpbl9oYW5kLCBuYS5ybSA9IFRSVUUpLA0KICAgICAgICAgICAgZmx5X2J5X2NvdW50ID0gc3VtKGZseV9ieSwgbmEucm0gPSBUUlVFKSkgDQpgYGANCg0KDQpgYGB7cn0NCmxpYnJhcnkobGVhZmxldCkNCmBgYA0KDQpgYGB7cn0NCg0KICBsZWFmbGV0KGRhdGEgPSBiaXJkc18yMSkgJT4lDQogIGFkZFRpbGVzKCkgJT4lICAjIEFkZCBkZWZhdWx0IE9wZW5TdHJlZXRNYXAgbWFwIHRpbGVzDQogIGFkZE1hcmtlcnMobGFiZWwgPSBiaXJkc185JGNvbW1vbl9uYW1lLCBjbHVzdGVyT3B0aW9ucyA9IG1hcmtlckNsdXN0ZXJPcHRpb25zKCkpIA0KICANCiAjIFByaW50IHRoZSBtYXANCmBgYA0KDQoNCi00NS45MTY2Nw0KMTY1LjQwMDANCg0KDQpgYGB7cn0NCnNlYWJpcmRzX2NsZWFuZWRfZGF0YQ0KYGBgDQoNCmBgYHtyfQ0Kc2hpcF9kYXRhIDwtIHJlYWRfZXhjZWwoaGVyZSgicmF3X2RhdGEvc2VhYmlyZHMueGxzIiksIA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzaGVldCA9ICJTaGlwIGRhdGEgYnkgcmVjb3JkIElEIikgJT4lIA0KICAgICAgICAgICAgICBjbGVhbl9uYW1lcygpDQoNCnBvc2l0aW9uIDwtIHNoaXBfZGF0YSAlPiUgDQogIHNlbGVjdChkYXRlLCBsYXQsIGxvbmcpICU+JQ0KICBmaWx0ZXIoIWlzLm5hKGxhdCksDQogICAgICAgICAhaXMubmEobG9uZykpICU+JSANCiAgZ3JvdXBfYnkoZGF0ZSkgJT4lIA0KICBzdW1tYXJpc2VfaWYoaXMubnVtZXJpYywgbWVhbikNCg0KcG9zaXRpb24NCmBgYA0KDQoNCg0KYGBge3J9DQpzaGlwX2RhdGEgJT4lIA0KICBzZWxlY3QoZGF0ZSwgbGF0LCBsb25nKSAlPiUNCiAgZmlsdGVyKGlzLm5hKGRhdGUpKQ0KYGBgDQoNCg0KDQpgYGB7cn0NCnRhaWwocG9zaXRpb24pDQpgYGANCg0KDQpgYGB7cn0NCmxlYWZsZXQoZGF0YSA9IHBvc2l0aW9uKSAlPiUNCiAgYWRkVGlsZXMoKSAlPiUgICMgQWRkIGRlZmF1bHQgT3BlblN0cmVldE1hcCBtYXAgdGlsZXMNCiAgYWRkTWFya2VycyhsYWJlbCA9IHBvc2l0aW9uJGRhdGUsIGNsdXN0ZXJPcHRpb25zID0gbWFya2VyQ2x1c3Rlck9wdGlvbnMoKSkgDQogIA0KICMgUHJpbnQgdGhlIG1hcA0KYGBgDQoNCiMgaHR0cHM6Ly9rYXRldG8ubmV0L25ldHdvcmstdmlzdWFsaXphdGlvbg0KIyBodHRwczovL3N0YWNrb3ZlcmZsb3cuY29tL3F1ZXN0aW9ucy8zODQzMjc4OC9ob3ctZG8taS12aXN1YWxpc2UtbXVsdGlwbGUtcm91dGVzLXVzaW5nLWxlYWZsZXQtaW4tcg0KDQoNCmBgYHtyfQ0KIyBodHRwczovL3JzdHVkaW8uZ2l0aHViLmlvL2xlYWZsZXQvbWFya2Vycy5odG1sDQojIGZpcnN0IDIwIHF1YWtlcw0KZGYuMjAgPC0gcXVha2VzWzE6MjAsXQ0KDQpnZXRDb2xvciA8LSBmdW5jdGlvbihxdWFrZXMpIHsNCiAgc2FwcGx5KHBvc2l0aW9uJGRhdGUsIGZ1bmN0aW9uKGRhdGUpIHsNCiAgaWYoZGF0ZSA8PSAxOTc5LTEyLTMxKSB7DQogICAgImdyZWVuIg0KICB9IGVsc2UgaWYoZGF0ZSA8PSAxOTg5LTEyLTMxKSB7DQogICAgIm9yYW5nZSINCiAgfSBlbHNlIHsNCiAgICAicmVkIg0KICB9IH0pDQp9DQoNCmljb25zIDwtIGF3ZXNvbWVJY29ucygNCiAgaWNvbiA9ICdpb3MtY2xvc2UnLA0KICBpY29uQ29sb3IgPSAnYmxhY2snLA0KICBsaWJyYXJ5ID0gJ2lvbicsDQogIG1hcmtlckNvbG9yID0gZ2V0Q29sb3IocG9zaXRpb24pDQopDQoNCmxlYWZsZXQocG9zaXRpb24pICU+JSBhZGRUaWxlcygpICU+JQ0KICBhZGRBd2Vzb21lTWFya2Vycyh+bG9uZywgfmxhdCwgaWNvbj1pY29ucywgbGFiZWw9fmFzLmNoYXJhY3RlcihkYXRlKSkNCmBgYA0KDQpgYGB7cn0NCmdldENvbG9yIDwtIGZ1bmN0aW9uKHF1YWtlcykgew0KICBzYXBwbHkocG9zaXRpb24kZGF0ZSwgZnVuY3Rpb24oZGF0ZSkgew0KICBpZihkYXRlICVpbiUgIl4xOTYiKSB7DQogICAgImdyZWVuIg0KICB9IGVsc2UgaWYoZGF0ZSAgJWluJSAiXjE5NyIpIHsNCiAgICAib3JhbmdlIg0KICB9IGVsc2UgaWYoZGF0ZSAgJWluJSAiXjE5OCIpIHsNCiAgICAiYmx1ZSINCiAgfSBlbHNlIHsNCiAgICAicmVkIg0KICB9IH0pDQp9DQoNCmljb25zIDwtIGF3ZXNvbWVJY29ucygNCiAgaWNvbiA9ICdpb3MtY2xvc2UnLA0KICBpY29uQ29sb3IgPSAnYmxhY2snLA0KICBsaWJyYXJ5ID0gJ2lvbicsDQogIG1hcmtlckNvbG9yID0gZ2V0Q29sb3IocG9zaXRpb24pDQopDQoNCmxlYWZsZXQocG9zaXRpb24pICU+JSBhZGRUaWxlcygpICU+JQ0KICBhZGRBd2Vzb21lTWFya2Vycyh+bG9uZywgfmxhdCwgaWNvbj1pY29ucywgbGFiZWw9fmFzLmNoYXJhY3RlcihkYXRlKSkNCmBgYA0KDQoNCmBgYHtyfQ0KZ2V0Q29sb3IgPC0gZnVuY3Rpb24ocXVha2VzKSB7DQogIHNhcHBseShwb3NpdGlvbiRkYXRlLCBmdW5jdGlvbihkYXRlKSB7DQogIGNhc2Vfd2hlbihzdHJfZGV0ZWN0KGRhdGUsIA0KICAgICAgICAgICAgIHJlZ2V4KCJeMTk2IiwgDQogICAgICAgICAgICAgICAgICAgaWdub3JlX2Nhc2UgPSBUUlVFKSkgfiAiZ3JlZW4iLA0KICAgICAgICAgICAgc3RyX2RldGVjdChkYXRlLCANCiAgICAgICAgICAgICByZWdleCgiXjE5NyIsIA0KICAgICAgICAgICAgICAgICAgIGlnbm9yZV9jYXNlID0gVFJVRSkpIH4gIm9yYW5nZSIsDQogICAgICAgICAgICAgc3RyX2RldGVjdChkYXRlLCANCiAgICAgICAgICAgICByZWdleCgiXjE5OCIsIA0KICAgICAgICAgICAgICAgICAgIGlnbm9yZV9jYXNlID0gVFJVRSkpIH4gImJsdWUiLA0KICAgICAgICAgICAgIHN0cl9kZXRlY3QoZGF0ZSwgDQogICAgICAgICAgICAgcmVnZXgoIl4xOTkiLCANCiAgICAgICAgICAgICAgICAgICBpZ25vcmVfY2FzZSA9IFRSVUUpKSB+ICJyZWQiDQogICAgDQogICkgfSkNCn0NCg0KaWNvbnMgPC0gYXdlc29tZUljb25zKA0KICBpY29uID0gJ2lvcy1jbG9zZScsDQogIGljb25Db2xvciA9ICdibGFjaycsDQogIGxpYnJhcnkgPSAnaW9uJywNCiAgbWFya2VyQ29sb3IgPSBnZXRDb2xvcihwb3NpdGlvbikNCikNCg0KbGVhZmxldChwb3NpdGlvbikgJT4lIGFkZFRpbGVzKCkgJT4lDQogIGFkZEF3ZXNvbWVNYXJrZXJzKH5sb25nLCB+bGF0LCBpY29uPWljb25zLCBsYWJlbD1+YXMuY2hhcmFjdGVyKGRhdGUpKQ0KYGBgDQoNCg0KDQoNCg0KDQpgYGB7cn0NCiMgaHR0cHM6Ly9zdGFja292ZXJmbG93LmNvbS9xdWVzdGlvbnMvNTYzNjI1MTkvaG93LXRvLWZpbHRlci1kYXRlLXJhbmdlLWZvci1yb3V0ZXMtaW4tci1sZWFmbGV0LXNoaW55LWFwcA0KDQpsaWJyYXJ5KGRwbHlyKQ0KbGlicmFyeShzaGlueSkNCmxpYnJhcnkobGVhZmxldCkNCmxpYnJhcnkocmVhZHhsKQ0KbGlicmFyeShSQ29sb3JCcmV3ZXIpDQpsaWJyYXJ5KG1hcHMpDQpsaWJyYXJ5KGxlYWZsZXQuZXh0cmFzKQ0KbGlicmFyeShodG1sd2lkZ2V0cykNCg0KDQoNCmRhdGFfZG90cyA9IHJlYWRfY3N2KCJ0ZXN0NC5jc3YiKQ0KDQoNCnVpIDwtIGJvb3RzdHJhcFBhZ2UoDQogIHRhZ3Mkc3R5bGUodHlwZSA9ICJ0ZXh0L2NzcyIsICJodG1sLCBib2R5IHt3aWR0aDoxMDAlO2hlaWdodDoxMDAlfSIpLA0KICBsZWFmbGV0T3V0cHV0KCJtYXAiLCB3aWR0aCA9ICIxMDAlIiwgaGVpZ2h0ID0gIjEwMCUiKSwNCiAgYWJzb2x1dGVQYW5lbCh0b3AgPSAxMCwgcmlnaHQgPSAxMCwNCg0KDQogICAgICAgICAgICAgICAgZGF0ZVJhbmdlSW5wdXQoImRhdGVSYW5nZSIsICJEYXRlIFJhbmdlIElucHV0Iiwgc3RhcnQgPSAgbWluKGRhdGFfZG90cyRzaGlwX2RhdGUpLCBlbmQgPSBtYXgoZGF0YV9kb3RzJHNoaXBfZGF0ZSkpDQoNCg0KICApDQopDQoNCg0Kc2VydmVyIDwtIGZ1bmN0aW9uKGlucHV0LCBvdXRwdXQpIHsNCg0KICAjbiA8LSA2MA0KICBxdWFsX2NvbF9wYWxzID0gYnJld2VyLnBhbC5pbmZvW2JyZXdlci5wYWwuaW5mbyRjYXRlZ29yeSA9PSAncXVhbCcsIF0NCiAgY29sX3ZlY3RvciA9IHVubGlzdChtYXBwbHkoYnJld2VyLnBhbCwgcXVhbF9jb2xfcGFscyRtYXhjb2xvcnMsIHJvd25hbWVzKHF1YWxfY29sX3BhbHMpKSkNCg0KDQogIG15TWFwID0gbGVhZmxldCgibWFwIikgJT4lIA0KICAgIGFkZFRpbGVzKGdyb3VwID0gIkJhc2UiKSAlPiUNCiAgICBhZGRQcm92aWRlclRpbGVzKHByb3ZpZGVycyRDYXJ0b0RCLlBvc2l0cm9uLCBncm91cCA9ICJHcmV5IikgJT4lDQogICAgYWRkUmVzZXRNYXBCdXR0b24oKQ0KDQoNCiAgcnYgPC0gcmVhY3RpdmVWYWx1ZXMoDQogICAgZmlsdGVyZWREYXRhID1kYXRhX2RvdHMsDQogICAgaWRzID0gdW5pcXVlKGRhdGFfZG90cyRSb3V0ZSkNCiAgKQ0KDQogIG9ic2VydmVFdmVudChpbnB1dCRkYXRlUmFuZ2UsIA0KICAgICAgICAgICAgICAge3J2JGZpbHRlcmVkRGF0YSA9IGRhdGFfZG90c1thcy5EYXRlKGRhdGFfZG90cyRzaGlwX2RhdGUpID49IGlucHV0JGRhdGVSYW5nZVsxXSAmIGFzLkRhdGUoZGF0YV9kb3RzJHNoaXBfZGF0ZSkgPD0gaW5wdXQkZGF0ZVJhbmdlWzJdLF0NCg0KICAgICAgICAgICAgICAgcnYkaWRzID0gdW5pcXVlKHJ2JGZpbHRlcmVkRGF0YSRSb3V0ZSkNCiAgICAgICAgICAgICAgIH0NCg0KICApDQoNCg0KDQogICMgSW5pdGlhdGUgdGhlIG1hcA0KICBvdXRwdXQkbWFwIDwtIHJlbmRlckxlYWZsZXQoew0KDQoNCiAgICBmb3IgKGkgaW4gcnYkaWRzKSB7DQogICAgICAjcHJpbnQoaSkNCiAgICAgIG15TWFwID0gbXlNYXAgJT4lDQogICAgICAgIGFkZFBvbHlsaW5lcygNCiAgICAgICAgICBkYXRhID0gc3Vic2V0KHJ2JGZpbHRlcmVkRGF0YSwgUm91dGUgPT0gaSksDQogICAgICAgICAgd2VpZ2h0ID0gMywNCiAgICAgICAgICBjb2xvciA9IHNhbXBsZShjb2xfdmVjdG9yLCAxKSwNCiAgICAgICAgICBvcGFjaXR5ID0gMC44LA0KICAgICAgICAgIHNtb290aEZhY3RvciA9IDEsDQogICAgICAgICAgbG5nID0gfkRsb25nLCANCiAgICAgICAgICBsYXQgPSB+RGxhdCwNCiAgICAgICAgICBoaWdobGlnaHQgPSBoaWdobGlnaHRPcHRpb25zKA0KICAgICAgICAgICAgd2VpZ2h0ID0gNSwNCiAgICAgICAgICAgIGNvbG9yID0gImJsdWUiLA0KICAgICAgICAgICAgYnJpbmdUb0Zyb250ID0gVFJVRQ0KICAgICAgICAgICksDQogICAgICAgICAgbGFiZWwgPSB+IGFzLmNoYXJhY3RlcihTaGlwbWVudElEKSwNCiAgICAgICAgICBwb3B1cCA9IH4gYXMuY2hhcmFjdGVyKFNoaXBtZW50SUQpLA0KICAgICAgICAgIGdyb3VwID0gInRlc3QiDQogICAgICAgICkNCg0KDQogICAgfQ0KICAgIG15TWFwDQoNCg0KICB9KQ0KDQoNCn0NCnNoaW55QXBwKHVpID0gdWksIHNlcnZlciA9IHNlcnZlcikNCmBgYA0KDQpgYGB7cn0NCmRhdGFfZG90cyAlPiUgDQogIG11dGF0ZShzaGlwX2RhdGUgPSBhcy5EYXRlKHNoaXBfZGF0ZSwgIiV5LyVtLyVkIiksDQogICAgICAgICBkZWxpdmVyeV9kYXRlID0gYXMuRGF0ZShkZWxpdmVyeV9kYXRlLCAiJXkvJW0vJWQiKSkNCmBgYA0KDQo=